<template>
  <div class="myEdit">
    <v-md-editor
      class="markdown"
      v-model="article.context"
      :mode="mode"
      :tab-size="tabSize"
      :toc-nav-position-right="tocNavPositionRight"
      :default-show-toc="defaultShowToc"
      :placeholder="placeholder"
      :autofocus="autofocus"
      :default-fullscreen="defaultFullscreen"
      :include-level="includeLevel"
      :left-toolbar="leftToolbar"
      :right-toolbar="rightToolbar"
      :toolbar-config="toolbarConfig"
      :toolbar="toolbar"
      :disabled-menus="disabledMenus"
      :upload-image-config="uploadImageConfig"
      :before-preview-change="beforePreviewChange"
      :codemirror-config="codemirrorConfig"
      :codemirror-style-reset="codemirrorStyleReset"
      @upload-image="handleUploadImage"
      @copy-code-success="handleCopyCodeSuccess"
      height="100%"
    ></v-md-editor>
    <van-popup v-model="show" round closeable position="bottom" :style="{ height: '50%' }">
      <van-form @submit="onSubmit">
        <van-field v-model.trim="article.title" name="title" label="文章标题" placeholder="文章标题" :rules="[{ required: true, message: '请填写文章名称' }]" />
        <van-field v-model.trim="article.articleDesc" name="articleDesc" label="文章描述" placeholder="文章描述" :rules="[{ required: true, message: '请填写文章描述信息' }]" />
        <van-field readonly clickable label="文章分类" placeholder="点击选择文章分类" @click="showPicker = true" />
        <van-field>
          <template #input>
            <van-tag plain closeable type="primary" v-for="(tag, index) in tagInfoIndexList" :key="tag.id" @close="tagClose(index)">{{ tag.tagName }}</van-tag>
          </template>
        </van-field>
        <van-popup v-model="showPicker" position="bottom">
          <van-picker show-toolbar :columns="tagList" @confirm="tagOnConfirm" @cancel="showPicker = false" />
        </van-popup>
        <van-field name="uploader" label="上传文章封面">
          <template #input>
            <van-uploader v-model="fileList" multiple :max-count="1" :max-size="3 * 1024 * 1024" @oversize="onOversize" :after-read="afterRead" :before-read="beforeRead" :before-delete="beforeDelete" />
          </template>
        </van-field>
        <div style="margin: 16px">
          <van-button round block type="info" native-type="submit">发布</van-button>
        </div>
      </van-form>
      <div style="margin: 16px"><van-button round block type="info" @click="saveDraft">保存草稿</van-button></div>
    </van-popup>
  </div>
</template>

<script>
// import exportFile from '@/utils/exportFile'
import { Toast } from 'vant'
import requestApi from '@/utils/request.js'

export default {
  name: 'MyEditComponent',
  props: {
    mode: {
      type: String,
      default: 'editable'
    }
  },
  data() {
    const then = this
    return {
      showPicker: false,
      fileList: [],
      isUploadImage: false,
      article: {
        articleDesc: '',
        title: '',
        thumb: '',
        author: '',
        tagNames: [],
        articleType: 0,
        context: '## 点击保存按钮 发布文章！！！' // 内容
      },
      tagList: ['Java', 'Linux', 'Docker'],
      tagInfoList: [],
      tagInfoIndexList: [],
      show: false,
      tabSize: 2, // 制表符长度
      defaultShowToc: false, // 是否默认显示目录导航
      tocNavPositionRight: false, // 目录导航是否在右侧,
      placeholder: '请使用markdown语法编写', // 提示信息
      autofocus: false, // 编辑器加载完是否自动聚焦
      defaultFullscreen: false, // 是否默认开启全屏
      includeLevel: [1, 2, 3], // 目录导航生成时包含的标题。默认包含 2 级、3 级标题。
      leftToolbar: 'h bold italic strikethrough quote | ul ol table hr | link image code | undo redo clear | export', // 左侧工具栏
      rightToolbar: 'preview toc sync-scroll fullscreen', // 右侧工具栏
      // 内置 toolbar 的一些配置
      toolbarConfig: {
        'image-link': {
          // 是否在插入图片链接的时候默认带上width height 属性，默认值：false
          insertWithSize: false
        }
      },
      disabledMenus: ['save'], // 禁用菜单  ['image/upload-image',h/h1]
      uploadImageConfig: { accept: 'image/*' }, // 上传本地图片的相关配置
      codemirrorConfig: {}, // 初始化 Codemirror 的配置。将会与内部的默认的配置合并
      codemirrorStyleReset: true, // 是否对 codemirror 编辑器的部分样式进行优化。若关闭，则会恢复 codemirror 编辑器默认的样式
      // 自定义工具栏
      toolbar: {
        export: {
          title: '发布',
          icon: 'v-md-icon-save',
          action(editor) {
            if (then.article.context === null || then.article.context.length === 0) {
              Toast.fail('文章内容不能为空')
              return
            }
            then.article.context = editor.text
            then.show = true
          }
        }
      }
    }
  },
  created() {
    this.getTags()
  },
  methods: {
    getTags() {
      const then = this
      // 获取tag标签
      requestApi
        .get('getTags')
        .then(function (response) {
          const req = response.data
          if (req.code === 0) {
            then.tagInfoList = req.data
            const tagNameList = req.data.map(o => {
              return [o.tagName].toString()
            })
            then.tagList = tagNameList
          }
        })
        .catch(function (error) {
          console.log(error)
          Toast.fail('获取文章分类错误')
        })
    },
    tagOnConfirm(value, index) {
      if (this.tagInfoIndexList.length === 3) {
        this.showPicker = false
        Toast.fail('最多只能添加三个标签')
        return
      }
      if (this.checkTagNameData(this.tagInfoList[index], this.tagInfoIndexList)) {
        this.tagInfoIndexList.push(this.tagInfoList[index])
        this.showPicker = false
      } else {
        Toast.fail('标签已存在 请勿重复添加')
      }
    },
    // 校验tag表示重复添加
    checkTagNameData(value, list) {
      for (let i = 0; i < list.length; i++) {
        if (list[i].tagName === value.tagName) {
          return false
        }
      }
      return true
    },
    // 可关闭的tag标签 关闭tag方法
    tagClose(index) {
      this.tagInfoIndexList.splice(index, 1)
    },
    // 上传文件之前的操作
    beforeRead(file) {
      if (!/\.(jpg|jpeg|png|GIF|JPG|PNG)$/.test(file.name)) {
        Toast.fail('上传文件格式错误 请重新上传')
        return false
      }
      if (file.size / 1024 > 1024 * 3) {
        Toast.fail('上传文件超过限制 请重新上传')
        return false
      }
      return true
    },
    // 上传完成之后的操作
    afterRead(file) {
      // 上传图片需要转换二进制这里要用到FormData
      const forms = new FormData()
      // 这里的file表示给后台传的属性名字，这里看接口文档需要传的的属性
      forms.append('file', file.file) // 获取上传图片信息
      // 向后端发送相应的请求
      // 这块的url是具体的交互接口
      // headers是上传图片需要用到的响应头，此处的token是后端那边给设置的，所以我请求的时候需要带上token，
      // token根据实际情况自行添加
      const token = localStorage.getItem('my_token')
      const then = this
      requestApi
        .post('uploadImage', forms, {
          headers: {
            'content-type': 'multipart/form-data',
            // 设置请求头
            Authorization: token
          }
        })
        .then(response => {
          const uploadFile = {
            url: '',
            status: 'uploading',
            message: '上传中...'
          }
          this.fileList[0] = uploadFile
          const res = response.data
          // 如果传入的响应状态码为200，则成功将文件发送给后台
          if (res.code === 0) {
            uploadFile.url = then.imageUrl + res.data.fileUrl

            uploadFile.status = 'done'
            uploadFile.message = ''
            this.isUploadImage = true
            Toast.success('文章图片上传成功')
          } else {
            uploadFile.url = ''
            uploadFile.status = 'failed'
            uploadFile.message = '上传失败'
            Toast.fail('文章图片上传错误') // 这块是请求失败后台给返回的相应的数据
          }
        })
        .catch(function (error) {
          console.log(error)
          Toast.fail('文章图片上传错误')
        })
    },
    // 删除之前的操作
    beforeDelete(file, dataUrl) {
      const token = localStorage.getItem('my_token')
      const uploadFile = this.fileList[0]
      const then = this
      requestApi({
        method: 'get',
        url: 'deleteImage',
        headers: {
          // 设置请求头
          Authorization: token
        },
        params: {
          fileUrl: uploadFile.url
        }
      })
        .then(response => {
          const res = response.data
          // 如果传入的响应状态码为0，则成功将文件发送给后台
          if (res.code === 0) {
            then.fileList = []
            this.isUploadImage = false
          } else {
            Toast.fail(res.msg) // 这块是请求失败后台给返回的相应的数据
          }
        })
        .catch(function (error) {
          console.log(error)
          Toast.fail('文章图片删除错误')
        })
    },
    // 上传图片超过限制大小的回调方法
    onOversize() {
      Toast.fail('文件大小不能超过 3MB')
    },
    // 在预览解析前触发的函数，配置此属性后必须要调用 next 方法并传入需要渲染的 md 文本，否则 preview 组件将不会进行渲染。
    beforePreviewChange(text, next) {
      next()
    },

    // 保存草稿
    saveDraft() {
      try {
        if (!/^.{5,20}$/.test(this.article.title)) {
          Toast.fail('文章标题格式错误 在5-20个字之间')
          return
        }
        if (!/^.{5,50}$/.test(this.article.articleDesc)) {
          Toast.fail('文章简介格式错误 在5-50个字之间')
          return
        }
        if (this.tagInfoIndexList.length === 0) {
          Toast.fail('文章标签不能为空')
          return
        }
        if (!this.isUploadImage) {
          Toast.fail('请上传文章图片')
          return
        }
        this.article.tagNames = this.tagInfoIndexList
        this.article.articleType = 0
        this.article.thumb = this.fileList[0].url
        const token = localStorage.getItem('my_token')
        const then = this
        requestApi
          .post(
            'saveArticle',
            {
              articleDesc: then.article.articleDesc,
              title: then.article.title,
              thumb: then.article.thumb,
              tagNames: then.article.tagNames,
              articleType: then.article.articleType,
              context: then.article.context
            },
            {
              headers: {
                // 设置请求头
                Authorization: token
              }
            }
          )
          .then(response => {
            const req = response.data
            if (req.code === 0) {
              this.show = false
              Toast.success('草稿保存成功')
              this.$router.push('/draft')
            } else {
              this.show = false
              Toast.fail(req.msg)
            }
          })
      } catch (error) {
        this.show = false
        console.log(error)
        Toast.fail('保存失败')
      }
    },

    // 发布文章
    // 导出文件
    // exportFile.getMDs(this.context, this.title)
    onSubmit(values) {
      try {
        if (!/^.{5,20}$/.test(values.title)) {
          Toast.fail('文章标题格式错误 在5-20个字之间')
          return
        }
        if (!/^.{5,50}$/.test(values.articleDesc)) {
          Toast.fail('文章简介格式错误 在5-50个字之间')
          return
        }
        if (this.tagInfoIndexList.length === 0) {
          Toast.fail('文章标签不能为空')
          return
        }
        if (!this.isUploadImage) {
          Toast.fail('请上传文章图片')
          return
        }
        this.article.title = values.title
        this.article.tagNames = this.tagInfoIndexList
        this.article.articleType = 1
        this.article.thumb = this.fileList[0].url
        const token = localStorage.getItem('my_token')
        const then = this
        requestApi
          .post(
            'saveArticle',
            {
              articleDesc: then.article.articleDesc,
              title: then.article.title,
              thumb: then.article.thumb,
              tagNames: then.article.tagNames,
              articleType: then.article.articleType,
              context: then.article.context
            },
            {
              headers: {
                // 设置请求头
                Authorization: token
              }
            }
          )
          .then(response => {
            const req = response.data
            if (req.code === 0) {
              this.show = false
              Toast.success('保存成功')
              this.$router.push('/special')
            } else {
              this.show = false
              Toast.fail(req.msg)
            }
          })
      } catch (error) {
        this.show = false
        console.log(error)
        Toast.fail('保存失败')
      }
    },
    handleUploadImage(event, insertImage, files) {
      // console.log(files)
      insertImage({
        url: 'http://127.0.0.1:9000/static/image/Default_avatar.jpg',
        desc: '七龙珠',
        width: 'auto',
        height: 'auto'
      })
    },
    // eslint-disable-next-line no-unused-vars
    handleCopyCodeSuccess(code) {}
  }
}
</script>

<style lang="less">
.markdown {
  .v-md-editor__toolbar-item {
    font-size: 20px !important;
  }
}
</style>
